/*
* Copyright (C) 2020 ~ 2024 chaigec All Rights Reserved.
*
* Author:     chaigec <chaigec@163.com>
* Maintainer: chaigec <chaigec@163.com>

 * Use of this source code is governed by MIT license that can be found in the
 * LICENSE file in the root of the source tree. All contributing project authors
 * may be found in the AUTHORS file in the root of the source tree.
*/

#ifndef MK_STATE_GRID_B_H
#define MK_STATE_GRID_B_H
#include "MkSip/MkSipServer.h"
#include "MkStateGridBDataType.h"
#include "MkUtil/MkRwLock.h"
#include "MkUtil/MkPtzCommand.h"

typedef struct _state_grid_b_start_param
{
    MkString                SipId;
    MkString                SipRealm;
    MkString                LocalHost;
    Uint16                  LocalPort;
    MkString                MappingHost;  //can set empty
    Uint16                  MappingPort;  //can set 0
    Uint32                  RegisterExpires;      //register expires second
    Uint32                  SubscribeExpires;     //subscribe expires second
    _state_grid_b_start_param()
    {
        SipId = "191210000000000000";
        SipRealm = "1912100000";
        LocalPort = 5060;
        MappingPort = 0;
        RegisterExpires = 3600;
        SubscribeExpires = 3600;
    }
}MkStateGridBStartParam;

namespace tinyxml2
{
    class XMLElement;
    class XMLDocument;
}
typedef MkFunction<void(Uint32 ErrorCode, const CMkStateGridBResponseBase* pResponse)> MkStateGridBResponseCallback;
typedef MkFunction <Uint32(const CMkStateGridBRequestBase* pRequest, const MkStateGridBResponseCallback& ResCb)> MkStateGridBRequestCallback;
class MkApi CMkStateGridB : public CMkSipServer
{
    typedef struct _request_param
    {
        MkStateGridBResponseCallback         ResCb;
        CMkTime                             RequestTime;
        MkString                            StrKey;
    }MkSGARequestParam;

    typedef struct _state_grid_b_router
    {
        MkString    Id;
        MkString    Realm;
        MkString    Host;
        Uint16      Port;
        BOOL        bTcp;
    }MkStateGridBRouter;
public:
    CMkStateGridB(CMkEventPool* pEventPool, CMkTimer* pTimer);
    virtual ~CMkStateGridB();

    Uint32 Start(const MkStateGridBStartParam& Param, const MkStateGridBRequestCallback& ReqCb);
    Uint32 Stop();

    Uint32 AddRouter(const MkString& RouterId, const MkString& Realm, const MkString& RemoteIp, Uint16 RemotePort, BOOL bTcp);
    Uint32 RegisterServer(const MkString& ServerId, Uint32 Expires, const MkStateGridBResponseCallback& ResCb);
    Uint32 RegisterServerWithRegisterId(const MkString& RegisterId, Uint32 Expires, const MkMapString& AuthorizationParam, const MkStateGridBResponseCallback& ResCb);
    Uint32 GetResourse(const MkString& RouterId, const MkString& DstId, Uint32 FromIndex, Uint32 ToIndex, const MkStateGridBResponseCallback& ResCb);
    Uint32 GetHistoryAlarm(const MkString& RouterId, const MkString& DstId, Uint32 AlarmType, const CMkTime& BeginTime, const CMkTime& EndTime, Uint32 Level, Uint32 FromIndex, Uint32 ToIndex, const MkStateGridBResponseCallback& ResCb);
    Uint32 FindRecord(const MkString& RouterId, const MkString& DstId, const MkStateGridBRecordType& RecordType, const CMkTime& BeginTime, const CMkTime& EndTime, Uint32 FromIndex, Uint32 ToIndex, const MkStateGridBResponseCallback& ResCb);
    Uint32 InviteStream(const MkString& RouterId, const MkString& DstId, const MkString& OfferSdp, const MkStateGridBResponseCallback& ResCb);
    //cmd from page 79-80
    Uint32 PtzControl(const MkString& RouterId, const MkString& DstId, const MkStateGridPtzCommandType& Cmd, Uint32 Param1, Uint32 Param2, Uint32 Param3, const MkStateGridBResponseCallback& ResCb);

    Uint32 EventSubscribe(const MkString& RouterId, const MkString& DstId, Uint32 Expires, const MkStateGridBSubscribeType& SubscribeType, const MkMap<MkString, Uint32>& MapSubId, const MkStateGridBResponseCallback& ResCb);

    Uint32 StopEventSubscirbe(const MkString& SubscribeId, const MkStateGridBSubscribeType& SubscribeType, const MkStateGridBResponseCallback& ResCb);
    Uint32 ByeStream(const MkString& SessionId, const MkStateGridBResponseCallback& ResCb);

    Uint32 AlarmNotify(const MkString& SubId, const MkString& StrState, const MkString& Code, const MkString& Name, const Uint32 AlarmType, const CMkTime& StartTime, const CMkTime& EndTime, const MkStateGridBResponseCallback& ResCb);
    Uint32 StateNotify(const MkString& SubId, const MkString& StrState, const MkString& Code, const MkString& Name, Uint32 Status, const MkStateGridBResponseCallback& ResCb);
    Uint32 ResourcePush(const MkString& RouterId, const MkString& DstId, const MkString& ParentId, const MkMapStateGridBResourse& MapResource, const MkStateGridBResponseCallback& ResCb);

private:
    Uint32 OnSipRequest(const MkSipRequestEvent& RequestEvent, const CMkSipMessage& SipRequest, const EventRequestCallback& Cb) override;
    Uint32 OnSipResponse(const MkSipResponseEvent& ResponseEvent, const MkString& TransActionId, const CMkSipMessage& SipRequest, const CMkSipMessage& SipResponse, const EventResponseCallback& Cb) override;

    Uint32 RegisterRequestParse(const CMkSipMessage& SipRequest, const EventRequestCallback& EventCallback);
    Uint32 NotifyRequestParse(const CMkSipMessage& SipRequest, const EventRequestCallback& EventCallback);
    Uint32 MessageRequestParse(const CMkSipMessage& SipRequest, const EventRequestCallback& EventCallback);
    Uint32 SubscribeRequestParse(const CMkSipMessage& SipRequest, const EventRequestCallback& EventCallback);
    Uint32 InviteRequestParse(const CMkSipMessage& SipRequest, const EventRequestCallback& EventCallback);
    Uint32 SubscribeNotifyRequestParse(const CMkSipMessage& SipRequest, const EventRequestCallback& EventCallback);
    Uint32 ByeParse(const CMkSipMessage& SipRequest, const EventRequestCallback& EventCallback);

    Uint32 MessageGetResouceRequestParse(const MkString& RouterId, const tinyxml2::XMLElement *pElement, const EventRequestCallback& EventCallback);
    Uint32 MessageGetRecordRequestParse(const MkString& RouterId, const tinyxml2::XMLElement *pElement, const EventRequestCallback& EventCallback);
    Uint32 MessageGetAlarmRequestParse(const MkString& RouterId, const tinyxml2::XMLElement *pElement, const EventRequestCallback& EventCallback);

    Uint32 NotifyRequestXmlParse(const MkString& XmlBody, const MkString& RouterId, const EventRequestCallback& EventCallback);
    Uint32 NotifyRequestResoursePushParse(const tinyxml2::XMLElement *pElement, const MkString& RouterId, const EventRequestCallback& EventCallback);

    Uint32 RegisterResponseParse(const MkString& TransActionId, const CMkSipMessage& SipRequest, const CMkSipMessage& SipResponse);

    Uint32 MessageResponseParse(const MkString& TransActionId, const CMkSipMessage& SipRequest, const CMkSipMessage& SipResponse);
    Uint32 MessageResponseResourceParse(const tinyxml2::XMLElement *pElement, const MkString& RouterId, const MkString& TransActionId);
    Uint32 MessageResponseHistoryAlarmParse(const tinyxml2::XMLElement *pElement, const MkString& RouterId, const MkString& TransActionId);
    Uint32 MessageResponseHistoryRecordParse(const tinyxml2::XMLElement *pElement, const MkString& RouterId, const MkString& TransActionId);

    Uint32 InviteResponseParse(const MkString& TransActionId, const CMkSipMessage& SipRequest, const CMkSipMessage& SipResponse, const EventResponseCallback& Cb);
    Uint32 SubscribeResponseParse(const MkString& TransActionId, const CMkSipMessage& SipRequest, const CMkSipMessage& SipResponse);
private:
    Uint32 ResponseCallback(Uint32 ErrorCode, const MkString& strKey, const CMkStateGridBResponseBase* pRes);

    Uint32 DeleteRouter(const MkString& RouterId);
    Uint32 GetRouter(const MkString& RouterId, MkStateGridBRouter& Router);
    Uint32 AddReqeust(const MkString& strKey, const MkStateGridBResponseCallback& ResCb);
private:
    MkStateGridBRequestCallback              m_Callback;
    Uint32                                  m_RegisterExpries;
    Uint32                                  m_SubscribeExpires;
    CMkRwLock                               m_ReqLock;
    MkMap<MkString, MkSGARequestParam>      m_MapRequst;
    CMkRwLock                               m_RouterLock;
    MkMap<MkString, MkStateGridBRouter>     m_MapGbRouter; //key router id
};




#endif
